Write is an extensible text editor for the Oberon system. It is based on a few simple concepts and aims at typical writing tasks, such as memos and reports. It does not try to support a document model, and it is not fully "wysiwyg". To arrive at a rather simple implementation, the few concepts provided have been carried out with all consequences. This should be kept in mind before considering a certain behaviour of the editor to be a "bug". The following tutorial assumes that the reader already knows how to use the Oberon system, especially, how to handle viewers, files, and commands.
Principles
A Write text models a sequence of characters. Besides standard characters, Write supports special user extensible characters. Such characters, called elements, float in the text just as ordinary characters do. Typical elements support the integration of graphics and the like into texts. A standard extension of elements allows for separating the text into paragraphs. Such elements are called paragraph controls or parc for short. A parc defines the paragraph attributes for all characters following it up to the next parc or the end of the text.
Mouse commands are interpreted by Write just as defined by Edit. Exceptions to that occur when clicking on an element. Here, the element is free to consume (and act on) the mouse click, overriding the standard behaviour. This is used by parcs to support interactive setting of paragraph attributes.
Insertion of new characters into the text requires setting the caret left to the character before which to insert, or to the end of the text. Selecting a stretch of the text corresponds to selecting a range of characters. The visible selection extends from the beginning of the first selected character to the beginning of the first character behind the selection or the end of the text. Hence, selections always reflect the exact area which is affected when changing or deleting.
Editing
Basic editing functionality is just as in Edit. This includes scrolling, setting the caret, selecting text, inserting, copying, and deleting text stretches, and changing attributes of characters. The cursor left/right keys move the caret. To support editing indented text (like programs), the Linefeed key can be used instead of Carriage-Return. This will indent the next line to the same level as the previous one. The cursor left/right keys will shift indented text if it is selected in the focus viewer with the caret invisible. Furthermore, when extending a selection over two consecutive viewers, Write adds visual feedback. This avoids the danger of extending a selection by mistake and then deleting or copying a far larger stretch of text than was intended. See below for a description of commands that further support basic editing.
In order to insert a parc into a text, place the caret at the appropriate position and press BREAK. This will copy the parc above the caret position (or the default parc if there is none above). A parc is displayed as a separation line corresponding to the width set for that paragraph. Above that separation line, one or two marks signal the formatting mode of the paragraph: a single mark at the very left, in the middle, or at the very right indicates left flush, centered, or right flush formatting, respectively. Two marks at both ends indicate block (fully justified) formatting. Below the separation line, set tabs are indicated by marks. Pressing Shift-BREAK inserts a parc which forces a page break (attribute break=before). Such parcs are displayed using a solid separation line.
A parc defines a special behaviour for middle-button mouse clicks. It has two separate sensitive areas. One above and one below the separation line. The following table shows how various middle mouse button clicks and interclicks affect the paragraph attributes bound to a parc. Again, see the commands below for further manipulations of parcs.
where buttons effect
above separation line, left end middle inset left margin
above separation line, left end middle + right symmetric inset of left & right margin
above separation line, right end middle inset right margin
above separation line, right end middle + right symmetric inset of left & right margin
above separation line, towards left end middle left flush formatting
above separation line, in the middle middle centered formatting
above separation line, towards right end middle right flush formatting
above separation line middle + left block formatting
below separation line, no tab mark hit middle create new tab
below separation line, tab mark hit middle move tab
below separation line, tab mark hit middle + right move tab and all subsequent tabs in synch
below separation line, tab mark hit middle + left delete tab
Printing
When printing a text, Write reformats individual paragraphs for the printer. Write preserves all user setable measures, while individual words may be placed differently. This allows for optimal display of texts on the screen, while at the same time fully exploiting the printer resolution. Hence, it should not be tried to affect the placing of individual words by inserting additional blanks or the like! Furthermore, Write ignores all empty space at the beginning of a page except when preceded by a parc with enforced page break attribute. White space in this sense are empty lines (a single blank makes a line non-empty!) and lead-space defined by a parc. Refer to the print command description below for details on how to initiate a printout.
In order to achieve good results, the Lm3 metrics files for the used font families should be available. For example, when using the fonts Syntax12, Math12, Syntax14, and LetterHead, the metrics files Syntax.Lm3.Fnt, Math.Lm3.Fnt, and LetterHead.Lm3.Fnt are required. If a metrics file for a used font is missing, the printer metrics are estimated using a simple heuristics based on the screen font metrics. Beware: this leads to at most draft quality of the printed text.
Commands in the Viewer Menu
Write.Search
Takes the most recent selection as search argument. If the selection is older than the latest one used for Write.Search, the previously set search argument will be used. Write.Search starts searching at the current caret position, or at the beginning of the text, if no caret is set. When starting the search behind the last occurence of the search pattern, the search will automatically wrap around and start over again at the beginning of the text.
Write.Replace
Takes the most recent selection as replacement argument. If the selection is older than the latest one used for Write.Replace, the previously set replacement argument will be used. Write.Replace verifies that the pattern right to the current caret position matches the current search argument. If so, it is replaced and Write.Replace automatically searches for the next occurence. Write.Replace does not wrap around when searching.
Write.ReplaceAll
To make Write.ReplaceAll usable, the separating space in the menu has to be deleted. Write.ReplaceAll operates much the same way as Write.Replace does. Additionally, the replacing process is carried on to the end of the text. Write.ReplaceAll does not wrap around when searching.
Write.Store
Stores the text. After completing, Write.Store writes out the number of characters in the text. Whenever the text displayed in a Write viewer has been changed but not yet stored, the menu bar contains an exclamation mark following the Write.Store command.
Commands in the Write Tool
The following commands are supported by Write. Generally, the standard Write tool contains several examples on how to use the Write commands, most of which should be self-explaining. For each command, the parameters directly following the command are given. Furthermore, most of the commands take further implicit parameters, like the current selection, the current focus (the caret), and the selection in the currently marked viewer. Such parameters are also listed below. Whenever the marked viewer (or the selection in its body frame) is taken as a parameter, the viewer is expected to display a Write text. The selection symbol "^" adds a level of indirection by taking the explicit parameters of the command from the current selection. Explicit parameters may be names (sequences of characters starting with a letter, followed by letters, digits, or periods), strings (sequence of characters enclosed by quotes), or numbers (sequences of characters starting with a minus or a digit, followed by digits).
command explicit parameters implicit parameters
Write.Open ("^" | name)
Opens a Write viewer displaying the named text.
Write.SysOpen ("^" | name)
Opens a Write viewer in the system track displaying the named text. The default formatting uses a reduced width and a regular tabulator setting every 5mm.
Write.Store name marked viewer
Takes the text displayed in the marked viewer and stores it under the given name. The total number of bytes taken by the created file is written to the log.
Prints a list of Write texts. The print options are explained in a separate table below. Unless specified otherwise (using the /p option), Write.Print will assign consecutive page numbers to all texts printed with a single print command. As feedback, Write.Print writes the name and the number of copies of each printed text to the system log. Also, a period is written to the log for each page sent to the printer.
Write.Recall caret
Inserts the most recently deleted text stretch at the current caret position. Write.Recall can be used repeatedly to insert a deleted portion at several places. (Edit.Recall does nothing when applied to a Write text.)
Write.InsertParc caret
Inserts a new default parc at the current caret position.
Write.Locate ("^" | number) marked viewer
Locates a character position and makes it visible in the marked viewer. (Do not use Edit.Locate to locate a position in a Write text!)
Write.SelectParc caret
Make visible the parc corresponding to the paragraph containing the caret and select it.
Write.ChangeFont ("^" | name) selection in marked viewer
Change the font attribute of the selected characters in the marked viewer.
Write.ChangeColor ("^" | number) selection in marked viewer
Change the color attribute of the selected characters in the marked viewer. (Has no visible effect on monochrome monitors, on color monitors; 0 is the background and 15 the foreground color.)
Write.ChangeOffset ("^" | number) selection in marked viewer
Change the vertical offset attribute of the selected characters in the marked viewer (-128..127). The offset is specified in 1/64th of the font height of the affected character.
Write.Set ("^" | {attribute-name [values]}) selected parc in marked viewer
Sets paragraph attributes bound to the selected parc. The paragraph attributes are explained in a separate table below.
Write.Get ("^" | attribute-name) selected parc in marked viewer
Gets paragraph attributes bound to the selected parc. The paragraph attributes are the same as for Write.Set. If no special paragraph attribute is selected, all attributes will be shown.
Write.MakeDefault selected parc in marked viewer
Sets the default formatting of the marked text to the attributes of the selected parc.
Write.ShowAliens marked viewer
Searches the marked text for undefined elements. Such elements occur, if a text is opened while some defining modules of extended elements are not available. Write displays undefined elements uniformly as an empty frame. Write.ShowAliens list the position of such elements, as well as the names of the missing modules. Note that undefined elements can be selected, copied and deleted freely. As soon as the missing module become available, it is sufficient to reopen affected texts and the elements will again behave as originally intended.
Print Options
option function
"/a" alternating pages - different page formatting for even and odd page numbers
"/c" number request a certain number of copies to be printed (1..9)
"/f" name select font other than the system default font for headers and page numbers
"/h" request a header (file name plus print date) on each page
"/l" number add horicontal offset (in 1/10 mm) to page image
"/p" number start page numbering at a certain number (otherwise it starts at 0)
"/p" "f" suppress page number on first page
"/p" "n" suprress page numbers
"/s" number [number] select page(s) to print (the numbering corresponds to the one set by /p)
Paragraph Attributes
All numerical values are to be specified in 1/10 mm units (e.g. the value 150 corresponds to 1.5 cm).
attribute value(s) default function
"adjust" block | center | left | right left formatting mode
"break" before | normal normal if before, force page break immediately before parc
"grid" on | off off line grid
"lead" name | number | "default" 0 leading paragraph space (name specifies model font)
"left" number | "default" 0 left margin
"line" name | number | "default" 34 (Syntax10) minimal line height (name specifies model font)
"tabs" ("*" number | {number} "~") ~ tab spacing (every n, or enumerated)
"width" number | "default" 1650 maximal line width
The line spacing model assumes a minimal line height for each paragraph. If a line exceeds its minimal line height, it is automatically adjusted to avoid clutter between it and the line above it. If the line grid is turned on for that paragraph (default), the line is adjusted to an integer multiple of the minimal line height.
Advise: In order to reach a typographically sound layout, in most cases a single line height should be selected for all paragraphs of the text. To get good results when combining a font for body text with larger ones for titles and section headings and smaller ones for captions, it is useful to set the line height to the body font and turn the line grid on. In most cases, it is preferable to set line height and paragraph leadings using the name of the predominant font ("model font").
Write Tools
A collection of utility commands most of which operate equally well on standard texts and Write texts. (The application to Leda texts is not recommended - the standard Leda Attributes Viewer should be used in conjunction with Leda.Search and Leda.Replace.)
command explicit parameters implicit parameters
WriteTools.GetAttr selected character
Get textual attributes of the selected character: ASCII code, font name, color, and vertical offset.
WriteTools.IncSize ("^" | number) selection
Increment font sizes in selected range (negative increments may be used to decrement sizes). If a computed font is not available, the old font is retained.
Change fonts within the selected range. If a font is not available, the old font is retained.
WriteTools.Words ("^" | {name} "~")
Counts characters and words in the listed files.
WriteTools.Cleanup ("^" | {name} "~")
Scans a Write text and removes alien and ill-sized elements. (Restricted in use to Write texts.)
Elements
For a documentation of existing Write elements, cf. Elem.Guide.Txt - For a tutorial on how to design and implement Write elements, cf. WriteElems.Guide.Txt.